import ReactDOM from 'react-dom';
import React, { useState, useEffect } from 'react';
import { Loading } from '@alifd/next';
import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils';
import ReactRenderer from '@alilc/lowcode-react-renderer';
import { injectComponents } from '@alilc/lowcode-plugin-inject';
import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
import { getLowcodeModuleById } from '@/services/mockApi';
import { createUmiRequestHandler } from '@/low-code/request';
import utils from '@/low-code/utils';
import constants from '@/low-code/constants';
import { history } from 'umi';
import {
  getProjectSchemaFromLocalStorage,
  getPackagesFromLocalStorage,
} from '@/low-code/services/mockService';

const SamplePreview = ({ params }) => {
  //console.log(111);
  const [data, setData] = useState({});
  const [scenarioName, setScenarioName] = useState<string>(params.scenarioName);
  const [moduleId, setModuleId] = useState<number>(params.moduleId);
  const [error, setError] = useState<boolean>(false);
  const type = params.type;
  if (params.scenarioName) {
    if (scenarioName !== params.scenarioName) {
      setScenarioName(params.scenarioName);
      setData({});
    }
  } else if (params.moduleId) {
    if (moduleId !== params.moduleId) {
      setModuleId(params.moduleId);
      setData({});
    }
  }
  async function init() {
    let packages = null;
    let projectSchema = null;

    if (scenarioName) {
      packages = getPackagesFromLocalStorage(scenarioName);
      projectSchema = getProjectSchemaFromLocalStorage(scenarioName);
    } else if (moduleId) {
      const res = await getLowcodeModuleById(moduleId);
      const moduleData = res.data[0];
      if (moduleData) {
        const lowcodeData = {
          schema: type == 'preview' ? moduleData.schema : moduleData.release_schema,
          packages: type == 'preview' ? moduleData.packages : moduleData.release_packages,
        };

        if (lowcodeData.schema && lowcodeData.packages) {
          packages = JSON.parse(lowcodeData.packages);
          projectSchema = JSON.parse(lowcodeData.schema);
        } else {
          history.push('/404');
          setError(true);
          return;
        }
      } else {
        history.push('/404');
        setError(true);
        return;
      }
    } else {
      history.push('/404');
      setError(true);
      return;
    }
    //console.log(projectSchema, packages);
    const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
    const componentsMap: any = {};
    componentsMapArray.forEach((component: any) => {
      componentsMap[component.componentName] = component;
    });
    const schema = componentsTree[0];

    const libraryMap = {};
    const libraryAsset = [];
    packages.forEach(({ package: _package, library, urls, renderUrls }) => {
      libraryMap[_package] = library;
      if (renderUrls) {
        libraryAsset.push(renderUrls);
      } else if (urls) {
        libraryAsset.push(urls);
      }
    });

    const vendors = [assetBundle(libraryAsset, AssetLevel.Library)];

    // TODO asset may cause pollution
    const assetLoader = new AssetLoader();
    await assetLoader.load(libraryAsset);
    const components = await injectComponents(buildComponents(libraryMap, componentsMap));
    setData({
      schema,
      components,
    });
  }
  const { schema, components } = data;
  if (!schema || !components) {
    init();
    return (
      <div
        style={{
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'center',
          marginTop: '200px',
        }}
      >
        <Loading />
      </div>
    );
  }

  //console.log(schema, components);
  if (error) {
    return <></>;
  } else {
    return (
      <div className="lowcode-plugin-sample-preview">
        <ReactRenderer
          className="lowcode-plugin-sample-preview-content"
          schema={schema}
          components={components}
          appHelper={{
            requestHandlersMap: {
              //fetch: createFetchHandler(),
              fetch: createUmiRequestHandler(),
            },
            utils,
            constants,
          }}
        />
      </div>
    );
  }
};

export default function (params) {
  ReactDOM.render(<SamplePreview params={params} />, document.getElementById('lowcode-preview'));
}
